<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Limitations</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../atomic.html" title="Chapter 6. Boost.Atomic">
<link rel="prev" href="usage_examples.html" title="Usage examples">
<link rel="next" href="porting.html" title="Porting">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="usage_examples.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="porting.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="atomic.limitations"></a><a class="link" href="limitations.html" title="Limitations">Limitations</a>
</h2></div></div></div>
<p>
      While <span class="bold"><strong>Boost.Atomic</strong></span> strives to implement the
      atomic operations from C++11 and later as faithfully as possible, there are
      a few limitations that cannot be lifted without compiler support:
    </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
          <span class="bold"><strong>Aggregate initialization syntax is not supported</strong></span>:
          Since <span class="bold"><strong>Boost.Atomic</strong></span> sometimes uses storage
          type that is different from the value type, the <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code> template needs an initialization
          constructor that performs the necessary conversion. This makes <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code>
          a non-aggregate type and prohibits aggregate initialization syntax (<code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="special">{</span><span class="number">10</span><span class="special">}</span></code>).
          <span class="bold"><strong>Boost.Atomic</strong></span> does support direct and unified
          initialization syntax though. <span class="bold"><strong>Advice</strong></span>:
          Always use direct initialization (<code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">10</span><span class="special">)</span></code>)
          or unified initialization (<code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">{</span><span class="number">10</span><span class="special">}</span></code>)
          syntax.
        </li>
<li class="listitem">
          <span class="bold"><strong>Initializing constructor is not <code class="computeroutput"><span class="keyword">constexpr</span></code>
          for some types</strong></span>: For value types other than integral types,
          <code class="computeroutput"><span class="keyword">bool</span></code>, enums, floating point
          types and classes without padding, <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code> initializing constructor needs
          to perform runtime conversion to the storage type and potentially clear
          padding bits. This limitation may be lifted for more categories of types
          in the future.
        </li>
<li class="listitem">
          <span class="bold"><strong>Default constructor is not trivial in C++03</strong></span>:
          Because the initializing constructor has to be defined in <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code>,
          the default constructor must also be defined. In C++03 the constructor
          cannot be defined as defaulted and therefore it is not trivial. In C++11
          the constructor is defaulted (and trivial, if the default constructor of
          the value type is). In any case, the default constructor of <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code>
          performs default initialization of the atomic value, as required in C++11.
          <span class="bold"><strong>Advice</strong></span>: In C++03, do not use <span class="bold"><strong>Boost.Atomic</strong></span> in contexts where trivial default constructor
          is important (e.g. as a global variable which is required to be statically
          initialized).
        </li>
<li class="listitem">
          <span class="bold"><strong>C++03 compilers may transform computation dependency
          to control dependency</strong></span>: Crucially, <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
          only affects computationally-dependent operations, but in general there
          is nothing preventing a compiler from transforming a computation dependency
          into a control dependency. A fully compliant C++11 compiler would be forbidden
          from such a transformation, but in practice most if not all compilers have
          chosen to promote <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
          to <code class="computeroutput"><span class="identifier">memory_order_acquire</span></code>
          instead (see <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448" target="_top">this</a>
          gcc bug for example). In the current implementation <span class="bold"><strong>Boost.Atomic</strong></span>
          follows that trend, but this may change in the future. <span class="bold"><strong>Advice</strong></span>:
          In general, avoid <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
          and use <code class="computeroutput"><span class="identifier">memory_order_acquire</span></code>
          instead. Use <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
          only in conjunction with pointer values, and only if you can ensure that
          the compiler cannot speculate and transform these into control dependencies.
        </li>
<li class="listitem">
          <span class="bold"><strong>Fence operations may enforce "too strong"
          compiler ordering</strong></span>: Semantically, <code class="computeroutput"><span class="identifier">memory_order_acquire</span></code>/<code class="computeroutput"><span class="identifier">memory_order_consume</span></code> and <code class="computeroutput"><span class="identifier">memory_order_release</span></code> need to restrain
          reordering of memory operations only in one direction. Since in C++03 there
          is no way to express this constraint to the compiler, these act as "full
          compiler barriers" in C++03 implementation. In corner cases this may
          result in a slightly less efficient code than a C++11 compiler could generate.
          <span class="bold"><strong>Boost.Atomic</strong></span> will use compiler intrinsics,
          if possible, to express the proper ordering constraints.
        </li>
<li class="listitem">
          <span class="bold"><strong>Atomic operations may enforce "too strong"
          memory ordering in debug mode</strong></span>: On some compilers, disabling
          optimizations makes it impossible to provide memory ordering constraints
          as compile-time constants to the compiler intrinsics. This causes the compiler
          to silently ignore the provided constraints and choose the "strongest"
          memory order (<code class="computeroutput"><span class="identifier">memory_order_seq_cst</span></code>)
          to generate code. Not only this reduces performance, this may hide bugs
          in the user's code (e.g. if the user used a wrong memory order constraint,
          which caused a data race). <span class="bold"><strong>Advice</strong></span>: Always
          test your code with optimizations enabled.
        </li>
<li class="listitem">
          <span class="bold"><strong>No interprocess fallback</strong></span>: using <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
          in shared memory only works correctly, if <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">is_lock_free</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>.
          Same with <code class="computeroutput"><span class="identifier">atomic_ref</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>.
          <span class="bold"><strong>Advice</strong></span>: Use <a class="link" href="interface.html#atomic.interface.interface_ipc" title="Atomic types for inter-process communication">IPC
          atomic types</a> for inter-process communication.
        </li>
<li class="listitem">
          <span class="bold"><strong>Memory type requirements</strong></span>: Atomic objects
          cannot be placed in read-only memory, even if they are only read from.
          Here, read-only means that the memory region is mapped with read-only permissions
          by the OS, regardless of the <code class="computeroutput"><span class="keyword">const</span></code>-qualification.
          <span class="bold"><strong>Boost.Atomic</strong></span> may implement load operations
          using read-modify-write instructions on some targets, such as <code class="computeroutput"><span class="identifier">CMPXCHG16B</span></code> on x86. The load operation
          does not change the object value, but the instruction issues a write to
          the memory location nonetheless, so the memory must be writable. There
          may be other hardware-specific restrictions on the memory types that can
          be used with atomic instructions. Also, the operating system may have additional
          restrictions on the memory type and the set of allowed operations on it
          to implement waiting and notifying operations correctly. Such requirements
          are system-specific. For example, on Mac OS IPC atomics cannot be placed
          in stack memory, as notifying operations may spuriously fail to wake up
          blocked threads. <span class="bold"><strong>Boost.Atomic</strong></span> aims to
          support more atomic types and operations natively, even if it means not
          supporting some rarely useful corner cases. <span class="bold"><strong>Advice</strong></span>:
          Non-IPC atomics can be safely used in regular read-write process-local
          memory (e.g. stack or obtained via <code class="computeroutput"><span class="identifier">malloc</span></code>
          or <code class="computeroutput"><span class="keyword">new</span></code>), and IPC atomics can
          be used in read-write process-shared memory (e.g. obtained via <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html" target="_top"><code class="computeroutput"><span class="identifier">shm_open</span></code></a>+ <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html" target="_top"><code class="computeroutput"><span class="identifier">mmap</span></code></a>). Any special memory types,
          such as mapped device memory or memory mapped with special caching strategies,
          are not guaranteed to work and are subject to system-specific restrictions.
        </li>
<li class="listitem">
          <span class="bold"><strong>Signed integers must use <a href="https://en.wikipedia.org/wiki/Two%27s_complement" target="_top">two's
          complement</a> representation</strong></span>: <span class="bold"><strong>Boost.Atomic</strong></span>
          makes this requirement in order to implement conversions between signed
          and unsigned integers internally. C++11 requires all atomic arithmetic
          operations on integers to be well defined according to two's complement
          arithmetics, which means that <span class="bold"><strong>Boost.Atomic</strong></span>
          has to operate on unsigned integers internally to avoid undefined behavior
          that results from signed integer overflows. Platforms with other signed
          integer representations are not supported. Note that C++20 makes two's
          complement representation of signed integers mandatory.
        </li>
<li class="listitem">
          <span class="bold"><strong>Limited support for types with padding bits</strong></span>:
          There is no portable way to clear the padding bits of an object. Doing
          so requires support from the compiler, which is typically available in
          compilers supporting C++20. Without clearing the padding, <code class="computeroutput"><span class="identifier">compare_exchange_strong</span></code>/<code class="computeroutput"><span class="identifier">compare_exchange_weak</span></code> are not able to
          function as intended, as they will fail spuriously because of mismatching
          contents in the padding. Note that other operations may be implemented
          in terms of <code class="computeroutput"><span class="identifier">compare_exchange_</span><span class="special">*</span></code> internally. If the compiler does not offer
          a way to clear padding bits, <span class="bold"><strong>Boost.Atomic</strong></span>
          does support padding bits for floating point types on platforms where the
          location of the padding bits is known at compile time, but otherwise types
          with padding cannot be supported. Note that, as discussed in <a class="link" href="interface.html#atomic.interface.interface_atomic_object" title="Atomic objects"><code class="computeroutput"><span class="identifier">atomic</span></code></a> description, unions with
          padding bits cannot be reliably supported even on compilers that do offer
          a way to clear the padding.
        </li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2011 Helge Bahmann<br>Copyright © 2012 Tim Blechmann<br>Copyright © 2013, 2017, 2018, 2020, 2021 Andrey Semashev<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="usage_examples.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="porting.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
